extends Node2D
#************************帮助************************
# 玩家信息处理
#var user_info : NakamaAPI.ApiAccount = await client.get_account_async(session) # 获取登录玩家信息
#_update_user_info(user_info.user.username,"不高兴") # 更新用户息
# 匹配方式
#await socket.add_matchmaker_async()
#await multiplayer_bridge.join_named_match("我的服务器") # 加入/创建指定房间
#socket.leave_match_async(matchmaker_matched.match_id) # 离开匹配房间
# 发送数据方式
#socket.send_match_state_async(matchmaker_matched.match_id,1,"烽烟起寻爱似浪淘沙") # 发送原生功能数据
#_send_message.rpc({"message":"烽烟起寻爱似浪淘沙"}) # 发送rpc数据
# 好友系统
#_add_friends(["JXXZNQGUCp"]) # 添加好友
#_get_friends(0) # 获取好友
#_remove_firends(["JXXZNQGUCp"]) # 移除好友
#_block_friends(["JXXZNQGUCp"]) # 屏蔽好友
#************************帮助************************

signal _on_socket_connected # 服务器连接功
signal _on_socket_connection_error # 服务器连接失败
signal _on_socket_closed # 关闭服务器连接
signal _on_socket_received_error(p_error : NakamaException) # Nakama原生匹配连接信号事件
signal _on_socket_received_match_presence(p_match_presence_event : NakamaRTAPI.MatchPresenceEvent) # Nakama原生匹配加入/离开信号事件
signal _on_socket_received_match_state(match_state : NakamaRTAPI.MatchData) # Nakama原生匹配发送消息信号事件
signal _on_received_matchmaker_matched(matched : NakamaRTAPI.MatchmakerMatched) # Nakama规则匹配成功号事件
signal _on_bridge_match_joined() # Nakama桥接匹配成功信号事件
signal _on_bridge_match_join_error(exception : NakamaException) # Nakama桥接匹配失败信号事件
signal _on_peer_connected(id : int) # Godot多人网络连接信号事件
signal _on_peer_disconnected(id : int) # Godot多人网络断连信号事件

# 会话
var session : NakamaSession
# 客户端
var client : NakamaClient
# 套接字
var socket : NakamaSocket
# Godot原生多人桥接
var multiplayer_bridge : NakamaMultiplayerBridge
# 随机匹配组
var matchmaker_matched : NakamaRTAPI.Match

func _ready() -> void:
	_init_nakama_link()

# 初始化Nakama连接
func _init_nakama_link() -> void :
	# 初始化Nakama组件
	client = Nakama.create_client("defaultkey", "119.3.227.224")
	socket = Nakama.create_socket_from(client)
	_init_nakama_signal()
	_init_nakama_multiplayer_bridge() # 初始化多人桥接

# 主动触发连接
func _connect_server(user_name : String) -> NakamaException :
	session = await client.authenticate_custom_async(user_name)
	if session.is_exception() : return session.exception
	var connect_result : NakamaAsyncResult = await socket.connect_async(session)
	return connect_result.exception

# 初始化Nakama信号
func _init_nakama_signal() -> void :
	socket.connected.connect(_on_socket_connected_event)
	socket.connection_error.connect(_on_socket_connection_error_event)
	socket.closed.connect(_on_socket_closed_event)
	socket.received_error.connect(_on_socket_received_error_event)
	socket.received_match_presence.connect(_on_socket_received_match_presence_event)
	socket.received_match_state.connect(_on_socket_received_match_state_event)
	socket.received_matchmaker_matched.connect(_on_received_matchmaker_matched_event)

# 初始化Nakama桥接功能
func _init_nakama_multiplayer_bridge() -> void :
	multiplayer_bridge = NakamaMultiplayerBridge.new(socket)
	multiplayer_bridge.match_joined.connect(_on_bridge_match_joined_event)
	multiplayer_bridge.match_join_error.connect(_on_bridge_match_join_error_event)
	multiplayer.set_multiplayer_peer(multiplayer_bridge.multiplayer_peer)
	multiplayer.peer_connected.connect(_on_peer_connected_event)
	multiplayer.peer_disconnected.connect(_on_peer_disconnected_event)

# Nakama服务器接成功信号事件
func _on_socket_connected_event() :
	print("服务器连接功")
	_on_socket_connected.emit()

# Nakama服务器接失败信号事件
func _on_socket_connection_error_event() :
	print("服务器连接失败")
	_on_socket_connection_error.emit()

# Nakama服务器接失败信号事件
func _on_socket_closed_event() :
	print("关闭服务器连接")
	_on_socket_closed.emit()

# Nakama原生匹配连接信号事件
func _on_socket_received_error_event(p_error : NakamaException) :
	print("连接报错：", p_error)
	_on_socket_received_error.emit(p_error)

# Nakama原生匹配加入/离开信号事件
func _on_socket_received_match_presence_event(p_match_presence_event : NakamaRTAPI.MatchPresenceEvent) :
	var joins = p_match_presence_event.joins
	if joins :
		print(joins[0].username,"加入房间")
	var leaves = p_match_presence_event.leaves
	if leaves :
		print(leaves[0].username,"离开房间")
	_on_socket_received_match_presence.emit(p_match_presence_event)

# Nakama原生匹配发送消息信号事件
func _on_socket_received_match_state_event(match_state : NakamaRTAPI.MatchData) :
	print(match_state.presence.username,":",match_state.data)
	_on_socket_received_match_state.emit(match_state)

# Nakama规则匹配成功号事件
func _on_received_matchmaker_matched_event(matched : NakamaRTAPI.MatchmakerMatched) -> void :
	matchmaker_matched = await socket.join_matched_async(matched) # 匹配成功后nakama连接
	_on_received_matchmaker_matched.emit(matched)

# Nakama桥接匹配成功信号事件
func _on_bridge_match_joined_event() :
	print("加入：",multiplayer_bridge.match_id,"房间成功")
	_on_bridge_match_joined.emit()

# Nakama桥接匹配失败信号事件
func _on_bridge_match_join_error_event(exception : NakamaException) :
	print("加入：",multiplayer_bridge.match_id,"房间错误",exception.message)
	_on_bridge_match_join_error.emit(exception)

# Godot多人网络连接信号事件
func _on_peer_connected_event(id : int) -> void :
	print("客户端：",id,"连接")
	_on_peer_connected.emit(id)

# Godot多人网络断连信号事件
func _on_peer_disconnected_event(id : int) -> void :
	print("客户端：",id,"断连")
	_on_peer_disconnected.emit(id)

# 获取登录人信息
func _get_account_async() -> NakamaAPI.ApiAccount :
	return await client.get_account_async(session)

# 更新Nakama玩家信息
func _update_user_info(username, displayname, avaterurl="", language="zh", location="china", time_zone="GMT+8") -> NakamaAsyncResult :
	return await client.update_account_async(session,username,displayname,avaterurl,language,location,time_zone)

# 加好友
func _add_friends(friend_names : Array[String]) -> NakamaAsyncResult :
	return await client.add_friends_async(session,null,friend_names)

# 获取好友
func _get_friends(state : int) -> Array[NakamaAPI.ApiFriend] :
	# state含义解释
	# 0:互为好友
	# 1:主动方添加好友，被加方未同意，主动方查询
	# 2:主动方添加好友，被加方未同意，被加方查询
	# 3:被屏蔽状态
	var result : NakamaAPI.ApiFriendList = await client.list_friends_async(session,state)
	if result.is_exception() : return []
	return result.friends

# 移除好友
func _remove_firends(friend_names : Array) -> void :
	var result : NakamaAsyncResult = await client.delete_friends_async(session,[],friend_names)
	if result.is_exception() : print("删除好友错误：",result.exception.message)

# 屏蔽好友
func _block_friends(friends_names : Array) -> void :
	var result : NakamaAsyncResult = await client.block_friends_async(session,[],friends_names)
	if result.is_exception() : print("屏蔽好友错误：",result.exception.message)

# 创建群组
func _create_group(group_name : String, desc : String = "", avatar_url : String = "", is_open : bool = true, max_count : int = 100) -> NakamaException :
	var result : NakamaAPI.ApiGroup = await client.create_group_async(session,group_name,desc,avatar_url,null,is_open,max_count)
	return result.exception

# 删除群组
func _remove_group(group_id : String) -> NakamaException :
	var result : NakamaAPI.ApiGroup = await client.delete_group_async(session,group_id)
	return result.exception

# 更新群组
func _update_group(group_id : String, group_name : String, desc : String = "", avatar_url : String = "", is_open : bool = true):
	var result : NakamaAsyncResult = await client.update_group_async(session,group_id,group_name,desc,avatar_url,null,is_open)
	return result.exception

# 获取用户群组
func _get_user_groups(user_id : String) -> NakamaAPI.ApiUserGroupList :
	return await client.list_user_groups_async(session,user_id)

# 获取群组
func _get_groups(group_name : String = "") -> NakamaAPI.ApiGroupList :
	return await client.list_groups_async(session,group_name)

# 加入群组
func _join_group(group_id : String) -> NakamaAsyncResult :
	return await client.join_group_async(session,group_id)

# 加入匹配
func _join_match(match_name : String = "") :
	# 匹配方式
	if match_name :
		await multiplayer_bridge.join_named_match(match_name) # 加入/创建指定房间
	else :
		await socket.add_matchmaker_async("*", 5, 5) # 匹配所有，固定五人

# 离开匹配
func _leave_math(match_id : String) -> void :
	socket.leave_match_async(match_id) # 离开匹配房间

# 发送Nakama消息
func _send_message(match_id : String, message : String):
	socket.send_match_state_async(match_id,1,message) # 发送原生功能数据
